home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
preccx
/
prccx240.lha
/
ccx.h
< prev
next >
Wrap
C/C++ Source or Header
|
1993-05-09
|
17KB
|
510 lines
# ifndef CC_H
# define CC_H
# ifdef __MSDOS__
# define p_memleft() coreleft()
# else
# define p_memleft() 32000
# endif
# define CHAR char
typedef CHAR *characters;
# define CHARS characters
/* standard clib */ /* p_gets is undefined, so set */
# include <stdio.h> /* it to gets, which is. */
# define p_gets(x) gets(x)
# define p_calloc(x,y) calloc((long)(x),(long)(y))
# define p_free(x) free((VOID *)(x))
# include <stdarg.h>
# include <string.h>
# include <setjmp.h>
# include <values.h>
/* default defs */
# ifndef VALUE
# define VALUE char * /* make sure you define VALUE !! */
# endif
# ifndef TOKEN
# define TOKEN char /* and TOKEN, if not int and char */
# endif
# ifndef PARAM
# define PARAM long /* VALUE=synthetic, PARAM=inherited */
# endif
# ifndef MAXPROGRAMSIZE
# define MAXPROGRAMSIZE 4096 /* 20K (chars) is often too big in DOS*/
# endif /* but this is prop. to line length */
# ifndef READBUFFERSIZE
# define READBUFFERSIZE 2048 /* ditto */
# endif /* because this IS the line length */
# ifndef STACKSIZE
# define STACKSIZE 4096 /* Very difficult to overun 2K ! */
# endif /* because this is nesting depth */
/* msdos defns */
# ifndef CONTEXTSTACKSIZE
# define CONTEXTSTACKSIZE 1024
# endif
# ifndef C_STACKSIZE
# define C_STACKSIZE 0x7FFF
# endif
# define MAXARGS 8 /* number of params catered for */
/* DON'T change it! */
# define P_STOP (PARAM)(MAXINT-3)
extern int yytchar; /* the last thing yylex saw */
extern int yylineno; /* line count */
/* I'll put in the decls for the yystuff here, in case they're needed */
extern int yylen;
extern int yylex();
extern char *yylloc;
extern VALUE yylval;
/* local defs */
# define OPCODE char
# define VOID void
/* typedefs */
typedef PARAM status; /* STATUS is returned by a PARSER */
# define STATUS status
typedef STATUS PARSER(); /* PARSER returns a STATUS */
# define TOPARSER *(PARSER*)
typedef VOID ACTION(); /* VALUE stack manipulation */
typedef int boolean; /* BOOLEAN is returned by a PREDICATE */
# define BOOLEAN boolean
typedef BOOLEAN PREDICATE(); /* PREDICATE returns a BOOLEAN */
typedef struct { /* an INSTRUCTION consists of ... */
OPCODE opcode; /* an OPCODE as opcode and ... */
union { /* an ACTION or ... */
ACTION *act; /* a literal as operand. */
TOKEN tok; /* The opcode selects the */
VALUE val;
PARAM par;
} operand; /* interpretation of the operand. */
} instruction;
# define INSTRUCTION instruction
typedef union { /* The VALUE stack actually contains */
VALUE val; /* STACKVALUES, which may be either */
TOKEN tok; /* VALUEs or TOKENs. TOKENs are */
PARAM par; /* ... */
} stackvalue; /* pushed when literals are hit. */
# define STACKVALUE stackvalue
typedef struct{ /* all the info required for a REWIND */
TOKEN *pstr;
STACKVALUE *value;
int pc;
int lineno;
/* INSTRUCTION instr;*/ /* will introduce for optimization */
} FRAME;
typedef struct {
int readbuffersize, /* READBUFFERSIZE */
maxprogramsize, /* MAXPROGRAMSIZE */
stacksize, /* STACKSIZE */
contextstacksize; /* CONTEXTSTACKSIZE */
} PRECC_DATA;
typedef INSTRUCTION *PROGRAM; /* a PROGRAM is a list of INSTRUCTIONs*/
/* instruction destructors and constructors */
# define Action(x) ((x).operand.act)
# define Token(x) ((x).operand.tok)
# define Param(x) ((x).operand.par)
# define Opcode(x) ((x).opcode)
# define Value(x) ((x).operand.val)
/* status macros */
# define BADSTATUS(x) (!(x)) /* BADSTATUS(x) is a PREDICATE */
# define GOODSTATUS(x) (x) /* as is GOODSTATUS(x) */
# define OK(x) ((x)||0xFFFF)
# define KO(x) 0
# define SUCCESS OK(1)
# define FAILURE KO(0)
/* input stream manipulations */
/* MARK has to be first line in a */
/* routine. 'string' is a reserved */
/* local variable, as is 'count'. */
/* The MARK sets string and count to */
/* the current parse point and pc. */
#define MARK {\
fsave(p_frame);\
fpush(p_frame);\
}
/* REWIND resets the parse point and */
/* to the MARK at the head of the fn.*/
/* provided that a new line hasn't */
/* already been read, in which case */
/* just go back as far as possible */
#define REWIND {\
fpop(p_frame);\
frestore(p_frame);\
}
/* MOVEON budges the high-water mark */
/* maxp up to the current parse pt. */
/*
* maxp+1 is the first address I have not yet written into. The TOKEN
* space should be occupied by a 0. maxp is the last position I have
* written into.
*
* pstr is the current TOKEN position. Notice that I am going to have to
* read one TOKEN into *pstr to start up?
*
* We start with pstr=maxp=&buffer, and *buffer=first token.
*/
#define MOVEON if(++pstr>maxp){ /* this next space not written into yet*/\
*pstr=(TOKEN)yylex();\
lvbuff[pstr-buffer]=yylval;\
maxp=pstr;\
}
/* RELEASE destroys the frame */
# define RELEASE fpop(p_frame)
/* the secret parse string and stacks */
extern TOKEN *pstr; /* parsed stream */
extern TOKEN *maxp; /* maximal parse point in stream */
extern TOKEN *buffer; /* where the pstr points to */
extern TOKEN *yybuffer; /* points to the buffer */
extern VALUE *lvbuff; /* corresponding yylvals */
extern VALUE *plval; /* and pointer */
extern INSTRUCTION *program;
extern int pc; /* program counter - counts up from 0 */
extern int passcount; /* number of cuts */
extern STACKVALUE *stack; /* the evaluation stack - either VALUEs
or TOKENs */
extern STACKVALUE *value; /* top of evaluation stack */
extern FRAME *fstack; /* top of frame stack ... */
extern FRAME *fptr; /* and pointer. */
extern FRAME p_frame; /* a frame cache */
extern INSTRUCTION instr; /* single instruction cache */
extern int call_mode; /* 0 for auto-calling convention, 1=manual */
extern int optimize; /* 1 = flying program optimization */
extern jmp_buf jmpb; /* environment */
extern int p_argc; /* main() arg count */
extern char **p_argv; /* main() arg vector*/
extern PRECC_DATA precc_data;
extern int msdos;
extern PARSER *p_entry;
extern int p_enargs;
extern PARAM p_eargv[MAXARGS];
/* opcodes */
# define INCR 5 /* increment value stack */
# define PARM 4 /* parameter to a function call */
# define FUNC 3 /* That's got an ACTION operand */
# define EXIT 2
# define CNST 1 /* That's got a VALUE operand. */
# define NOP 0 /* Saves time. */
/* program stack manipulation */
#define push(x) {if(pc>=precc_data.maxprogramsize-1){\
fprintf(stderr,"precc: program stack overflow (%d)\n",pc);\
exit(1);\
}\
program[pc++]=(x);\
}
# define pull(n) (pc-=(n))
# define pop(x) (x=program[--pc])
# define ppeek(x) (pc>0?x=program[pc-1]:((x).opcode=EXIT,(x)))
# define ppoke(x) {if(pc>0)program[pc-1]=(x);}
/* load and unlaod the current instruction */
#define getinstruction(n,x) {Opcode(instr)=(n);Action(instr)=(x);}
#define pushinstruction(n,x) {getinstruction(n,x);push(instr);}
#define gettoken(x) {Opcode(instr)=(CNST);Token(instr)=(TOKEN)(x);}
#define getparam(x) {Opcode(instr)=(PARM);Param(instr)=(PARAM)(x);}
#define getmanip(x) {Opcode(instr)=(INCR);Param(instr)=(PARAM)(x);}
#define getvalue(x) {Opcode(instr)=(CNST);Value(instr)=(VALUE)(x);}
#define pushTOKEN(x) {gettoken(x);push(instr);}
#define pushPARAM(x) {getparam(x);push(instr);}
#define pushVALUE(x) {getvalue(x);push(instr);}
#define pushACTION(x) pushinstruction(FUNC,(x))
#define pushEXIT pushinstruction(EXIT,0)
/* don't allow extra stack manips if call_mode=1 */
/* and let's try some on-the-fly optimisation */
#define pushMANIP(x) if(!call_mode){\
if(optimize&&(Opcode(ppeek(instr))==(INCR))){\
Param(instr) += (PARAM)(x);\
ppoke(instr);\
} else{\
getmanip(x);\
push(instr);\
}\
}
# define pushINCR pushMANIP(1)
# define pushDECR pushMANIP(-1)
# define pushNOP pushinstruction(NOP,0)
/* evaluation stack manipulation */
# define pushvalue(x) ((*value++).val)=(x)
# define pushparam(x) ((*value++).par)=(x)
# define pushtoken(x) ((*value++).val)=(VALUE)(x)
# define popvalue(x) (x=(*--value).val)
# define poptoken(x) (x=(TOKEN)(*--value).val)
# define popparam(x) (x=(*--value).par)
# define pullvalue(n) &((value-=(n))->val)
# define pullparam(n) &((value-=(n))->par)
# define pulltoken(n) &(TOKEN)((value-=(n))->val))
/*
# define pullvalue(n) &stack[(int)(value-=(n))-(int)stack].val
# define pullparam(n) &stack[(int)(value-=(n))-(int)stack].par
# define pulltoken(n) &stack[(int)(value-=(n))-(int)stack].tok
*/
/* frame stack manipulation */
# define fpush(x) (*fptr++=(x))
# define fpop(x) (x=*--fptr)
# define fpull(n) (fptr-=(n))
# define fsave(x) \
x.pstr=pstr;\
x.value=value;\
x.pc=pc;\
x.lineno=passcount
/*;\ ppeek(x.instr)*/
# define frestore(x) \
pstr=(x.lineno==passcount)?x.pstr:(btk_error(),buffer);\
pc=x.pc;\
value=x.value
/*; ppoke(x.instr)*/
/* multi-argument function call */
/* I have to use int's in the param list because of possible promotion */
# define CALL(p,m,a) {\
m=va_arg(ap,int);\
a=(PARAM*)ap; /* very NON-PORTABLE, but it's fast */\
ap=(va_list)&a[m];\
m++;\
switch(m-1) {\
case 0: p();break;\
case 1: p(a[0]);break;\
case 2: p(a[0],a[1]);break;\
case 3: p(a[0],a[1],a[2]);break;\
case 4: p(a[0],a[1],a[2],a[3]);break;\
case 5: p(a[0],a[1],a[2],a[3],a[4]);break;\
case 6: p(a[0],a[1],a[2],a[3],a[4],a[5]);break;\
case 7: p(a[0],a[1],a[2],a[3],a[4],a[5],a[6]);break;\
case 8: p(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7]);break;\
default: printf("error: too many (%d) args in CALL\n",m-1); exit(100);\
}\
}
# ifndef DOS
/* SUNUNIX versions */
# define setvalue(n) pullvalue(call_mode?(n)-1:0);value[-1].val
# define settoken(n) pullvalue(call_mode?(n)-1:0);(TOKEN)(value[-1].val)
# define refvalue(n) (value[(n)-2].val)
# define reftoken(n) (TOKEN)(value[(n)-2].val)
# define refpar(n) (value[(n)-2].par)
/*
# define refvalue(n) stack[(int)value+(n)-1-(int)stack].val
# define reftoken(n) stack[(int)value+(n)-1-(int)stack].tok
# define refpar(n) stack[(int)value+(n)-2-(int)stack].par
*/
# else
/* BORLAND versions */
# define setvalue(n) ((pullvalue(call_mode?(n)-1:0))[-1].val)
# define settoken(n) (TOKEN)((pullvalue(call_mode?(n)-1:0))[-1].val)
# define refvalue(n) (value[(n)-2].val)
# define reftoken(n) (TOKEN)(value[(n)-2].val)
# define refpar(n) (value[(n)-2].par)
# endif
/* program-interpreter */
/* in engine.c */
extern int p_evaluate();
/* read and run parser, interpret resulting program */
/* in engine.c */
extern ACTION p_run;
/* parsers without actions */
/* defined in cc.c */
extern PARSER p_andparse0;
extern PARSER p_orparse0;
extern PARSER p_many0;
extern PARSER p_iter0;
extern PARSER p_some0;
extern PARSER p_option0;
extern PARSER p_range0;
extern PARSER p_hidden0;
/* but here are macros */
# define p_andparse0(x,y) p_andparse0n(x,(char)0,y,(char)0)
# define p_orparse0(x,y) p_orparse0n(x,(char)0,y,(char)0)
# define p_many0(x) p_many0n(x,(char)0)
# define p_iter0(n,x) p_iter0n(n,x,(char)0)
# define p_some0(x) p_some0n(x,(char)0)
# define p_option0(x) p_option0n(x,(char)0)
# define p_range0(x) p_range0n(x,(char)0)
# define p_hidden0(x) p_hidden0n(x,(char)0)
/* defined in common.c */
extern PARSER p_nothing0;
extern PARSER p_anything0;
extern PARSER p_first0;
extern PARSER p_last0;
extern PARSER p_exactly0;
extern PARSER p_notexactly0;
extern PARSER p_attach0;
extern PARSER p_uniq0;
/* parsers with actions attached */
/* in cc.c */
extern PARSER p_attach;
extern PARSER p_prepend;
/* in common.c */
extern PARSER p_andparse;
extern PARSER p_orparse;
extern PARSER p_nothing;
extern PARSER p_option;
extern PARSER p_many;
extern PARSER p_iter;
extern PARSER p_some;
extern PARSER p_anything;
extern PARSER p_first;
extern PARSER p_last;
extern PARSER p_exactly;
extern PARSER p_notexactly;
extern PARSER p_range;
/* but replaced by macros here */
# define ATTACH(p,f) if(GOODSTATUS(p))pushACTION(f)
# define p_attach(x,y) p_attach0n(x,(char)0,y,(char)0)
# define p_prepend(x,y) p_prepend0n(x,(char)0,y,(char)0)
# define p_andparse(p,q,f) ATTACH(p_andparse0(p,q),f)
# define p_orparse(p,q,f) ATTACH(p_orparse0(p,q),f)
# define p_many(p,f) ATTACH(p_many0(p),f)
# define p_iter(n,p,f) ATTACH(p_iter0(n,p),f)
# define p_some(p,f) ATTACH(p_some0(p),f)
# define p_option(p,f) ATTACH(p_option0(p),f)
# define p_nothing(f) ATTACH(p_nothing0(),f)
# define p_anything(f) ATTACH(p_anything0(),f)
# define p_first(f) ATTACH(p_first0(),f)
# define p_last(f) ATTACH(p_last0(),f)
# define p_exactly(f) ATTACH(p_exactly0(),f)
# define p_notexactly(f) ATTACH(p_notexactly0(),f)
# define p_range(p,f) ATTACH(p_range0(p),f)
/*
*/
/* parsers taking a variable number of arguments */
extern STATUS p_andparse0n(PARSER *, ...);
extern STATUS p_orparse0n(PARSER *, ...);
extern STATUS p_option0n(PARSER *, ...);
extern STATUS p_hidden0n(PARSER *, ...);
extern STATUS p_many0n(PARSER *, ...);
extern STATUS p_iter0n(int, PARSER *, ...);
extern STATUS p_some0n(PARSER *, ...);
extern STATUS p_uniq0n(PARSER *, ...);
extern STATUS p_attach0n(PARSER *, ...);
extern STATUS p_prepend0n(ACTION *, ...);
extern STATUS p_range0n(PREDICATE *, ...);
extern PARSER p_test0;
/* actions*/
/* in common.c */
extern ACTION p_nop;
/* aux */
extern char *p_scpy();
extern void exit(int);
/* (in on_error.c) */
extern ACTION zer_error;
extern ACTION bad_error;
extern ACTION btk_error;
extern ACTION precc_begin;
extern ACTION precc_end;
/* lexer (in yystuff.c)*/
extern int yylex();
/* in engine.c */
extern PREDICATE mygets;
# ifndef BEGIN
# define BEGIN
# endif
# ifndef END
# define END
# endif
# ifndef BAD_ERROR /* failed parse marked at deepest pt */
# define BAD_ERROR(x) fprintf(stderr,"(line %d) error:\
parse failed near ..<>%s\n",yylineno,maxp);yylloc=NULL;
# endif
# ifndef ZER_ERROR /* incomplete parse shows remainder */
# define ZER_ERROR(x) fprintf(stderr,"(line %d) error:\
parse terminated early near ..<>%s\n",yylineno,maxp);yylloc=NULL;
# endif
# ifndef BTK_ERROR /* backtracking across a new line boundary */
# define BTK_ERROR(x) if (!p_entry) fprintf(stderr,"(line %d) error:\
parse backtracked across cut from point near <>%s\n\
",yylineno,maxp);yylloc=NULL;longjmp(jmpb,1);
# endif
# ifndef ON_ERROR /* default error mechanism */
# define ON_ERROR(x) switch(x){\
case 1:BAD_ERROR(1);break;\
case 0:ZER_ERROR(0);break;\
case -1:BTK_ERROR(-1);break;\
}
# endif
#define MAIN(x) \
int main(argc,argv)\
int argc; char **argv;\
{\
PARSER x;ACTION p_run;\
void precc_free(), precc_call();\
if (msdos) brk(C_STACKSIZE); /* set the C stack to 32K */\
p_argc=argc;p_argv=argv;\
precc_call();\
atexit(precc_free);\
p_run (x);\
return 0;\
}\
VOID zer_error(){ON_ERROR(0);}\
VOID bad_error(){ON_ERROR(1);}\
VOID btk_error(){ON_ERROR(-1);}\
VOID precc_begin(){BEGIN;}\
VOID precc_end(){END;}\
void precc_call(){ACTION p_creat_data;\
precc_data.readbuffersize=READBUFFERSIZE;\
precc_data.maxprogramsize=MAXPROGRAMSIZE;\
precc_data.stacksize=STACKSIZE;\
precc_data.contextstacksize=CONTEXTSTACKSIZE;\
p_creat_data();}\
void precc_free(){ACTION p_destr_data;p_destr_data();}
# define V(n) refvalue(n) /*n'th argument*/
# define T(n) reftoken(n) /*n'th argument*/
# define VV(n) setvalue(n) /*result from n args*/
# define TT(n) settoken(n) /*result from n args*/
# endif